package de.dhbw.studienarbeit;

import java.text.DateFormat;
import java.text.SimpleDateFormat;

import android.app.Service;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;

public class CalendarService extends Service {

	private static final String DEBUG_TAG = "CalendarService";
	
	@Override
	public IBinder onBind(Intent intent) {
		return null;
	}

	@Override
	public void onCreate() {
		Toast.makeText(this, "DHBW Service Started", Toast.LENGTH_LONG).show();
		Log.d(DEBUG_TAG, "OnCreate");
	}

	@Override
	public void onDestroy() {
		Toast.makeText(this, "DHBW Service Stopped", Toast.LENGTH_LONG).show();
		Log.d(DEBUG_TAG, "onDestroy");
	}

	public int onStartCommand(Intent intent, int flags, int startId) {
		// This is where the magic happens
		CalendarFoo(); 
		return START_STICKY;
	}
	
	public void CalendarFoo() {
	
		try {
			Log.i(DEBUG_TAG, "Starting Calendar Test");

			// ListAllCalendarDetails();

			// will return the last found calendar with "Test" in the name
			// int iTestCalendarID = ListSelectedCalendars();

			int dhbwCalendar = getDHBWCalendarId();

			Uri newEvent3 = MakeNewCalendarEntry3(dhbwCalendar, "Test",
					"Testeitnrag", "Bei mir");

			// ListAllCalendarEntries(dhbwCalendar);
			// change this when you know which calendar you want to use
			// If you create a new calendar, you may need to manually sync the
			// phone first
			/*
			 * if (iTestCalendarID != 0) {
			 * 
			 * Uri newEvent2 = MakeNewCalendarEntry2(iTestCalendarID); int
			 * eventID2 = Integer.parseInt(newEvent2.getLastPathSegment());
			 * ListCalendarEntry(eventID2);
			 * 
			 * Uri newEvent = MakeNewCalendarEntry(iTestCalendarID); int eventID
			 * = Integer.parseInt(newEvent.getLastPathSegment());
			 * ListCalendarEntry(eventID);
			 * 
			 * 
			 * Uri newEvent3 = MakeNewCalendarEntry3(iTestCalendarID, "Test",
			 * "Testeitnrag", "Bei mir"); int eventID3 =
			 * Integer.parseInt(newEvent.getLastPathSegment());
			 * ListCalendarEntry(eventID);
			 * 
			 * 
			 * 
			 * 
			 * // uncomment these to show updating and deleting entries
			 * 
			 * //UpdateCalendarEntry(eventID);
			 * //ListCalendarEntrySummary(eventID);
			 * //DeleteCalendarEntry(eventID);
			 * 
			 * //ListCalendarEntrySummary(eventID); //
			 * ListAllCalendarEntries(iTestCalendarID); } else {
			 * Log.i(DEBUG_TAG, "No 'Test' calendar found."); }
			 */
			Log.i(DEBUG_TAG, "Ending Calendar Test");

		} catch (Exception e) {
			Log.e(DEBUG_TAG, "General failure", e);
		}
	}
	
	/**
	 * Accepts Dates in RFC2445 Format and converts to Unix Time
	 * @param iCalFormat
	 * @return Unix Time
	 */
	@SuppressWarnings("unused")
	private long RFC2445toUnixTime(String iCalFormat) {
		DateFormat dfm = new SimpleDateFormat("yyyyMMddTHHmmss");
		return 0;
		
	}

	private int ListSelectedCalendars() {
		int result = 0;
		String[] projection = new String[] { "_id", "name" };
		String selection = "selected=1";
		String path = "calendars";

		Cursor managedCursor = getCalendarManagedCursor(projection, selection,
				path);

		if (managedCursor != null && managedCursor.moveToFirst()) {

			Log.i(DEBUG_TAG, "Listing Selected Calendars Only");
			
			int nameColumn = managedCursor.getColumnIndex("name");
			int idColumn = managedCursor.getColumnIndex("_id");

			do {
				String calName = managedCursor.getString(nameColumn);
				String calId = managedCursor.getString(idColumn);
				Log.i(DEBUG_TAG, "Found Calendar '" + calName + "' (ID="
						+ calId + ")");
				if (calName != null && calName.contains("Test")) {
					result = Integer.parseInt(calId);
				}
			} while (managedCursor.moveToNext());
		} else {
			Log.i(DEBUG_TAG, "No Calendars");
		}

		return result;
	}

	/**
	 * @return ID of calendar with name "DHBW" 
	 */
	private int getDHBWCalendarId() {
		int result = 0;
		String[] projection = new String[] { "_id", "name" };
		String selection = "selected=1";
		String path = "calendars";

		Cursor managedCursor = getCalendarManagedCursor(projection, selection,
				path);

		if (managedCursor != null && managedCursor.moveToFirst()) {

			Log.i(DEBUG_TAG, "Listing Selected Calendars Only");

			int nameColumn = managedCursor.getColumnIndex("name");
			int idColumn = managedCursor.getColumnIndex("_id");

			do {
				String calName = managedCursor.getString(nameColumn);
				String calId = managedCursor.getString(idColumn);
				Log.i(DEBUG_TAG, "Found Calendar '" + calName + "' (ID="
						+ calId + ")");
				if (calName != null && calName.equals("DHBW")) {
					result = Integer.parseInt(calId);
					Log.i(DEBUG_TAG, "DHBW calendar found, ID=" + calId);
				}
			} while (managedCursor.moveToNext());
		} else {
			Log.i(DEBUG_TAG, "No DHBW calendar found");
		}
		return result;
	}

	private void ListAllCalendarDetails() {
		Cursor managedCursor = getCalendarManagedCursor(null, null, "calendars");

		if (managedCursor != null && managedCursor.moveToFirst()) {

			Log.i(DEBUG_TAG, "Listing Calendars with Details");

			do {

				Log.i(DEBUG_TAG, "**START Calendar Description**");

				for (int i = 0; i < managedCursor.getColumnCount(); i++) {
					Log.i(DEBUG_TAG, managedCursor.getColumnName(i) + "="
							+ managedCursor.getString(i));
				}
				Log.i(DEBUG_TAG, "**END Calendar Description**");
			} while (managedCursor.moveToNext());
		} else {
			Log.i(DEBUG_TAG, "No Calendars");
		}

	}

	/**
	 * 
	 * @param calID
	 *            Calendar ID
	 * @param title
	 *            Title of Event
	 * @param starttime
	 *            Event start time
	 * @return EventId of duplicate Event, 0 if not duplicate
	 */
	private int isDuplicateEvent(int calID, String title, long starttime) {
		
		int eventId = 0;

		String[] projection = new String[] { "_id", "title", "dtstart" };
		Cursor managedCursor = getCalendarManagedCursor(projection,
				"calendar_id=" + calID, "events");

		if (managedCursor != null && managedCursor.moveToFirst()) {
			int dtstartColumn = managedCursor.getColumnIndex("dtstart");
			int titleColumn = managedCursor.getColumnIndex("title");
			int idColumn = managedCursor.getColumnIndex("_id");

			do {
				String actualTitle = managedCursor.getString(titleColumn);
				long actualStart = managedCursor.getLong(dtstartColumn);
				Log.i(DEBUG_TAG, "Title is " + actualTitle + " compared to: "
						+ title);
				Log.i(DEBUG_TAG, "Starttime is " + actualStart + " compared to: " + starttime);

				if (actualTitle.equals(title)) {
					eventId = managedCursor.getInt(idColumn);
					Log.i(DEBUG_TAG, "Event " + eventId + " is duplicate.");
				}

			} while (managedCursor.moveToNext());
		} else {
			Log.i(DEBUG_TAG, "No DHBW calendar found");
		}
		return eventId;
	}

	private void ListAllCalendarEntries(int calID) {

		Cursor managedCursor = getCalendarManagedCursor(null, "calendar_id="
				+ calID, "events");

		if (managedCursor != null && managedCursor.moveToFirst()) {

			Log.i(DEBUG_TAG, "Listing Calendar Event Details");

			do {

				Log.i(DEBUG_TAG, "**START Calendar Event Description**");

				for (int i = 0; i < managedCursor.getColumnCount(); i++) {
					Log.i(DEBUG_TAG, managedCursor.getColumnName(i) + "="
							+ managedCursor.getString(i));
				}
				Log.i(DEBUG_TAG, "**END Calendar Event Description**");
			} while (managedCursor.moveToNext());
		} else {
			Log.i(DEBUG_TAG, "No Calendars");
		}

	}

	private void ListCalendarEntry(int eventId) {
		Cursor managedCursor = getCalendarManagedCursor(null, null, "events/"
				+ eventId);

		if (managedCursor != null && managedCursor.moveToFirst()) {

			Log.i(DEBUG_TAG, "Listing Calendar Event Details");

			do {

				Log.i(DEBUG_TAG, "**START Calendar Event Description**");

				for (int i = 0; i < managedCursor.getColumnCount(); i++) {
					Log.i(DEBUG_TAG, managedCursor.getColumnName(i) + "="
							+ managedCursor.getString(i));
				}
				Log.i(DEBUG_TAG, "**END Calendar Event Description**");
			} while (managedCursor.moveToNext());
		} else {
			Log.i(DEBUG_TAG, "No Calendar Entry");
		}

	}

	private void ListCalendarEntrySummary(int eventId) {
		String[] projection = new String[] { "_id", "title", "dtstart" };
		Cursor managedCursor = getCalendarManagedCursor(projection, null,
				"events/" + eventId);

		if (managedCursor != null && managedCursor.moveToFirst()) {

			Log.i(DEBUG_TAG, "Listing Calendar Event Details");

			do {

				Log.i(DEBUG_TAG, "**START Calendar Event Description**");

				for (int i = 0; i < managedCursor.getColumnCount(); i++) {
					Log.i(DEBUG_TAG, managedCursor.getColumnName(i) + "="
							+ managedCursor.getString(i));
				}
				Log.i(DEBUG_TAG, "**END Calendar Event Description**");
			} while (managedCursor.moveToNext());
		} else {
			Log.i(DEBUG_TAG, "No Calendar Entry");
		}

	}

	private Uri MakeNewCalendarEntry(int calId) {
		ContentValues event = new ContentValues();

		event.put("calendar_id", calId);
		event.put("title", "Today's Event [TEST]");
		event.put("description", "2 Hour Presentation");
		event.put("eventLocation", "Online");

		long startTime = System.currentTimeMillis() + 1000 * 60 * 60;
		long endTime = System.currentTimeMillis() + 1000 * 60 * 60 * 2;

		event.put("dtstart", startTime);
		event.put("dtend", endTime);

		event.put("allDay", 0); // 0 for false, 1 for true
		event.put("eventStatus", 1);
		event.put("visibility", 0);
		event.put("transparency", 0);
		event.put("hasAlarm", 0); // 0 for false, 1 for true

		Uri eventsUri = Uri.parse(getCalendarUriBase() + "events");

		Uri insertedUri = getContentResolver().insert(eventsUri, event);
		return insertedUri;
	}

	private Uri MakeNewCalendarEntry2(int calId) {
		ContentValues event = new ContentValues();

		event.put("calendar_id", calId);
		event.put("title", "Birthday [TEST]");
		event.put("description", "All Day Event");
		event.put("eventLocation", "Worldwide");

		long startTime = System.currentTimeMillis() + 1000 * 60 * 60 * 24;

		event.put("dtstart", startTime);
		event.put("dtend", startTime);

		event.put("allDay", 1); // 0 for false, 1 for true
		event.put("eventStatus", 1);
		event.put("visibility", 0);
		event.put("transparency", 0);
		event.put("hasAlarm", 0); // 0 for false, 1 for true

		Uri eventsUri = Uri.parse(getCalendarUriBase() + "events");
		Uri insertedUri = getContentResolver().insert(eventsUri, event);
		return insertedUri;

	}

	/**
	 * @param calId
	 *            : Calender ID
	 * @param title
	 *            : Title of Calendar Entry
	 * @param desc
	 *            : Description
	 * @param loco
	 *            : Location
	 * @return inserted Uri
	 */
	private Uri MakeNewCalendarEntry3(int calId, String title, String desc,
			String loco) {
		// Default Kalender:
		// calId = 1;

		ContentValues event = new ContentValues();

		event.put("calendar_id", calId);
		event.put("title", title);
		event.put("description", desc);
		event.put("eventLocation", loco);

		long startTime = System.currentTimeMillis() + 1000 * 60 * 60;
		long endTime = System.currentTimeMillis() + 1000 * 60 * 60 * 2;

		event.put("dtstart", startTime);
		event.put("dtend", endTime);

		event.put("allDay", 0); // 0 for false, 1 for true
		event.put("eventStatus", 1);
		event.put("visibility", 0);
		event.put("transparency", 0);
		event.put("hasAlarm", 0); // 0 for false, 1 for true

		Uri eventsUri = Uri.parse(getCalendarUriBase() + "events");

		Uri insertedUri = getContentResolver().insert(eventsUri, event);
		return insertedUri;
	}

	private int UpdateCalendarEntry(int entryID) {
		int iNumRowsUpdated = 0;

		ContentValues event = new ContentValues();

		event.put("title", "Changed Event Title");
		event.put("hasAlarm", 1); // 0 for false, 1 for true

		Uri eventsUri = Uri.parse(getCalendarUriBase() + "events");
		Uri eventUri = ContentUris.withAppendedId(eventsUri, entryID);

		iNumRowsUpdated = getContentResolver().update(eventUri, event, null,
				null);

		Log.i(DEBUG_TAG, "Updated " + iNumRowsUpdated + " calendar entry.");

		return iNumRowsUpdated;
	}

	private int DeleteCalendarEntry(int entryID) {
		int iNumRowsDeleted = 0;

		Uri eventsUri = Uri.parse(getCalendarUriBase() + "events");
		Uri eventUri = ContentUris.withAppendedId(eventsUri, entryID);
		iNumRowsDeleted = getContentResolver().delete(eventUri, null, null);

		Log.i(DEBUG_TAG, "Deleted " + iNumRowsDeleted + " calendar entry.");

		return iNumRowsDeleted;
	}

	/**
	 * @param projection
	 * @param selection
	 * @param path
	 * @return
	 */
	private Cursor getCalendarManagedCursor(String[] projection,
			String selection, String path) {
		Uri calendars = Uri.parse("content://calendar/" + path);

		Cursor managedCursor = null;
		try {
			managedCursor = getContentResolver().query(calendars, projection, selection,
					null, null);
		} catch (IllegalArgumentException e) {
			Log.w(DEBUG_TAG,
					"Failed to get provider at [" + calendars.toString() + "]");
		}

		if (managedCursor == null) {
			// try again
			calendars = Uri.parse("content://com.android.calendar/" + path);
			try {
				managedCursor = getContentResolver().query(calendars, projection, selection,
						null, null);
			} catch (IllegalArgumentException e) {
				Log.w(DEBUG_TAG,
						"Failed to get provider at [" + calendars.toString()
								+ "]");
			}
		}
		return managedCursor;
	}

	/*
	 * Determines if it's a pre 2.1 or a 2.2 calendar Uri, and returns the Uri
	 */
	private String getCalendarUriBase() {
		String calendarUriBase = null;
		Uri calendars = Uri.parse("content://calendar/calendars");
		Cursor managedCursor = null;
		try {
			managedCursor = getContentResolver().query(calendars, null, null, null, null);
		} catch (Exception e) {
			// eat
		}

		if (managedCursor != null) {
			calendarUriBase = "content://calendar/";
		} else {
			calendars = Uri.parse("content://com.android.calendar/calendars");
			try {
				managedCursor = getContentResolver().query(calendars, null, null, null, null);
			} catch (Exception e) {
				// eat
			}

			if (managedCursor != null) {
				calendarUriBase = "content://com.android.calendar/";
			}

		}

		return calendarUriBase;
	}

}